現有的驗證器不夠⽤嗎?有幾種⽅式可以⾃訂驗證器:
class User < ActiveRecord::Base
validate :name_validator
private
def name_validator
unless name.starts_with? 'Ruby'
errors[:name] << "必須是 Ruby 開頭喔!"
end
end
end
注意:這個⽅法是 validate ,不是 validates 喔。
這種寫法滿簡單的,就是直接寫⼀個普通的⽅法(通常會放在 private 區塊),
當條件不符規定的時候,就在 errors 這個 Hash 裡⾯塞錯誤訊息。⽤起來就跟⼀
般的驗證器差不多:
$ bin/rails console
Running via Spring preloader in process 4628
Loading development environment (Rails 5.0.1)
>> user1 = User.new(name: "孫悟空")
=> #<User id: nil, name: "孫悟空", age: nil, email: nil, created_a
t: nil, updated_at: nil>
>> user1.save
(0.1ms) begin transaction
(0.3ms) rollback transaction
=> false
>> user1.errors.full_messages
=> ["Name 必須是 Ruby 開頭喔!"]
class User < ActiveRecord::Base
validates :name, presence: true, begin_with_ruby: true
end
這個驗證器可以跟其它內建的驗證器⼀起混著使⽤,使⽤起來會更簡潔。要寫這樣
的驗證器需要符合 Rails Validator 的命名規則:
class BeginWithRubyValidator < ActiveModel::EachValidator
def validate_each(record, attribute, value)
unless value.starts_with? 'Ruby'
record.errors[attribute] << "必須是 Ruby 開頭喔!"
end
end
end
在使⽤的時候,就是跟⼀般的 validates 差不多:
class User < ActiveRecord::Base
validates :name, begin_with_ruby: true
end
在 rails console 試⼀下效果:
$ bin/rails console
Running via Spring preloader in process 4750
Loading development environment (Rails 5.0.1)
>> user1 = User.new(name: "孫悟空")
=> #<User id: nil, name: "孫悟空", age: nil, email: nil, created_a
t: nil, updated_at: nil>
>> user1.save
(0.1ms) begin transaction
(0.0ms) rollback transaction
=> false
>> user1.errors.full_messages
=> ["Name 必須是 Ruby 開頭喔!"]
[為你自己學Ruby on Rails]https://railsbook.tw/chapters/08-ruby-basic-4.html